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/设计