ballerina編譯器已經集成了部分安全檢測,在編譯時能夠幫助咱們生成錯誤提示,同時ballerina 標準庫
已經對於常見漏洞高發的地方作了很好的處理,當咱們編寫了有安全隱患的代碼,編譯器就已經提示給
咱們了。
常見的問題sql
ballerina 標準庫對於安全敏感的函數以及操做使用@sensitive 註解進行說明,能夠確保容易出現漏洞的數據傳遞
給參數
好比,ballerina 標準庫的select api
public native function select(@sensitive string sqlQuery, typedesc? recordType, boolean loadToMemory = false, Param... parameters) returns @tainted table|error;
實際中咱們確定會碰到須要傳遞非可信數據,咱們能夠使用 untaint 表達式進行處理,同時對於返回值咱們能夠使用
@untainted 註解
參考安全
boolean isValid = isNumeric(studentId); if (isValid) { var dt = testDB->select("SELECT NAME FROM STUDENT WHERE ID = " + untaint studentId, ResultStudent); } function sanitizeSortColumn (string columnName) returns @untainted string { string sanitizedSortColumn = columnName; // Sanitize logic to make sure return value is safe return sanitizedSortColumn; }
ballerina 提供了api 能夠訪問不一樣源的配置信息,對於配置文件中包含密碼信息的必須加密
處理,框架提供了工具能夠對於配置進行加密框架
ballerina encrypt 按照提示輸入須要加密的名稱,會生成一個加密key,咱們能夠使用配置文件,或者環境變量獲取。 默認會找一個secret.txt的文件,裏面存儲了加密密鑰,請求以後會自動刪除,對於沒有這個文件的 會提示輸入密鑰
ballerina 的 http 服務能夠配置的方式加強認證以及受權,ballerina 支持jwt 以及basic 模式的認證,
使用basic模式時,用戶信息能夠經過配置文件加載,同時推薦使用https 方式進行數據訪問,加強
安全性ide
import ballerina/http; http:AuthProvider jwtAuthProvider = { scheme:"jwt", issuer:"ballerina", audience: "ballerina.io", clockSkew:10, certificateAlias: "ballerina", trustStore: { path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", password: "ballerina" } }; endpoint http:SecureListener secureHelloWorldEp { port:9091, authProviders:[jwtAuthProvider], secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", password: "ballerina" } } }; @http:ServiceConfig { basePath:"/hello" } service<http:Service> helloWorld bind secureHelloWorldEp { @http:ResourceConfig { methods:["GET"], path:"/" } sayHello (endpoint caller, http:Request req) { http:Response resp = new; resp.setTextPayload("Hello, World!"); _ = caller->respond(resp); } }
import ballerina/http; http:AuthProvider basicAuthProvider = { scheme:"basic", authStoreProvider:"config" }; endpoint http:SecureListener secureHelloWorldEp { port:9091, authProviders:[basicAuthProvider], secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", password: "ballerina" } } }; @http:ServiceConfig { basePath:"/hello", authConfig:{ scopes:["hello"] } } service<http:Service> helloWorld bind secureHelloWorldEp { @http:ResourceConfig { methods:["GET"], path:"/" } sayHello (endpoint caller, http:Request req) { http:Response resp = new; resp.setTextPayload("Hello, World!"); _ = caller->respond(resp); } }
用戶帳戶配置信息(經過配置文件)函數
sample-users.toml ["b7a.users"] ["b7a.users.generalUser"] password="@encrypted:{pIQrB9YfCQK1eIWH5d6UaZXA3zr+60JxSBcpa2PY7a8=}" ["b7a.users.admin"] password="@encrypted:{pIQrB9YfCQK1eIWH5d6UaZXA3zr+60JxSBcpa2PY7a8=}" scopes="hello"
加載配置工具
ballerina run --config sample-users.toml basic_auth_sample.bal
實際上就是在client 端加載認證信息,方便調用加密
import ballerina/http; http:AuthProvider jwtAuthProvider = { scheme:"jwt", propagateToken: true, issuer:"ballerina", audience: "ballerina.io", clockSkew:10, certificateAlias: "ballerina", trustStore: { path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", password: "ballerina" } }; endpoint http:SecureListener secureHelloWorldEp { port:9091, authProviders:[jwtAuthProvider], secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", password: "ballerina" } } }; endpoint http:Client downstreamServiceEP { url: "https://localhost:9092", auth: { scheme: http:JWT_AUTH }, secureSocket: { trustStore: { path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", password: "ballerina" } } }; @http:ServiceConfig { basePath:"/hello", authConfig:{ scopes:["hello"] } } service<http:Service> helloWorld bind secureHelloWorldEp { @http:ResourceConfig { methods:["GET"], path:"/" } sayHello (endpoint caller, http:Request req) { http:Response response = check downstreamServiceEP->get("/update-stats", message = untaint req); _ = caller->respond(response); } } // ---------------------------------------------- // Following code creates the downstream service // ---------------------------------------------- http:AuthProvider downstreamJwtAuthProvider = { scheme:"jwt", issuer:"ballerina", audience: "ballerina.io", clockSkew:10, certificateAlias: "ballerina", trustStore: { path: "${ballerina.home}/bre/security/ballerinaTruststore.p12", password: "ballerina" } }; endpoint http:SecureListener secureUpdateServiceEp { port:9092, authProviders:[downstreamJwtAuthProvider], secureSocket: { keyStore: { path: "${ballerina.home}/bre/security/ballerinaKeystore.p12", password: "ballerina" } } }; @http:ServiceConfig { basePath:"/update-stats" } service<http:Service> updateService bind secureUpdateServiceEp { @http:ResourceConfig { methods:["GET"], path:"/" } updateStats (endpoint caller, http:Request req) { http:Response resp = new; resp.setTextPayload("Downstream Service Received JWT: " + untaint req.getHeader("Authorization")); _ = caller->respond(resp); } }
ballerina 的設計以及功能仍是很方便的,功能很齊全。url
https://ballerina.io/learn/how-to-write-secure-ballerina-code/設計