ballerina编译器已经集成了部分安全检测,在编译时可以帮助我们生成错误提示,同时ballerina 标准库
已经对于常见漏洞高发的地方做了很好的处理,当我们编写了有安全隐患的代码,编译器就已经提示给
我们了。
常见的问题

  • sql 注入
  • path 操作
  • file 操作
  • 未授权文件访问
  • 为校验的重定向

确保ballerina 标准库的安全

ballerina 标准库对于安全敏感的函数以及操作使用@sensitive 注解进行说明,可以确保容易出现漏洞的数据传递
给参数
比如,ballerina 标准库的select

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;
}

保护密码以及secret key

ballerina 提供了api 可以访问不同源的配置信息,对于配置文件中包含密码信息的必须加密
处理,框架提供了工具可以对于配置进行加密

ballerina encrypt
按照提示输入需要加密的名称,会生成一个加密key,我们可以使用配置文件,或者环境变量获取。
默认会找一个secret.txt的文件,里面存储了加密密钥,请求之后会自动删除,对于没有这个文件的
会提示输入密钥

认证&&授权

ballerina 的 http 服务可以配置的方式增强认证以及授权,ballerina 支持jwt 以及basic 模式的认证,
使用basic模式时,用户信息可以通过配置文件加载,同时推荐使用https 方式进行数据访问,增强
安全性

  • jwt 认证
    可以通过http:AuthProvider 进行配置
    参考
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);
}
}
  • http basic 认证
    参考代码
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
  • 说明
    在认证服务的同时,我们可以配置scope,指定权限范围,还是比较方便的

下游服务的认证

实际上就是在client 端加载认证信息,方便调用

  • 一个jwt 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 的设计以及功能还是很方便的,功能很齐全。

参考资料

https://ballerina.io/learn/how-to-write-secure-ballerina-code/

 
 
 
 

ballerina 学习 三十二 编写安全的程序的更多相关文章

  1. ElasticSearch7.3学习(三十二)----logstash三大插件(input、filter、output)及其综合示例

    1. Logstash输入插件 1.1 input介绍 logstash支持很多数据源,比如说file,http,jdbc,s3等等 图片上面只是一少部分.详情见网址:https://www.elas ...

  2. ballerina 学习 三十 扩展开发(一)

    ballerina 主要是分为两大类 基于ballerina 语言开发的,一般是客户端的connector 使用java语言开发的(类似的基于jvm的都可以),一般是注解以及进行构件生成 baller ...

  3. Java开发学习(三十二)----Maven多环境配置切换与跳过测试的三种方式

    一.多环境开发 我们平常都是在自己的开发环境进行开发, 当开发完成后,需要把开发的功能部署到测试环境供测试人员进行测试使用, 等测试人员测试通过后,我们会将项目部署到生成环境上线使用. 这个时候就有一 ...

  4. Salesforce LWC学习(三十二)实现上传 Excel解析其内容

    本篇参考:salesforce lightning零基础学习(十七) 实现上传 Excel解析其内容 上一篇我们写了aura方式上传excel解析其内容.lwc作为salesforce的新宠儿,逐渐的 ...

  5. python学习 (三十二) 异常处理

    1 异常: def exceptionHandling(): try: a = b = d = a / b print(d) except ZeroDivisionError as ex: print ...

  6. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用

    JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...

  8. “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

随机推荐

  1. c++中的new和delete

    对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来了极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象.对于不能确定需要占用多少内存的情况,动态内 ...

  2. vijos1098 经典LIS变形

    合唱队形 描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1, ...

  3. java keytool详解

    Keytool 是一个Java 数据证书的管理工具 ,Keytool 将密钥(key)和证书(certificates)存在一个称为keystore的文件中. 在keystore里,包含两种数据:(1 ...

  4. 059——VUE中vue-router之路由嵌套在文章系统中的使用方法:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. uart boot log

    CC开始 xmodem 传输. 按 Ctrl+C 取消. 100% 95 KB 4 KB/s 00:00:23 0 Errors U-Boot SPL 2018.01 (Jan 16 2019 - 1 ...

  6. java 需要看的书籍

    参考链接:http://www.jianshu.com/p/454fc1e6cbe2 最近要看的有:Effective java  深入理解java 虚拟机  java 并发编程实战 (设计模式的书籍 ...

  7. bootstrap的学习总结

    1.bootstrap是一个css框架,它提供了很多类,这些类中实现了内外边距,颜色,大小等样式的封装,它还提供了很多常用插件可以直接使用 2.12栅格本质上是将标签的外边距和内边距通过“格子”的思想 ...

  8. Installing MIB in Ubuntu and Solving the Error “SNMP Cannot Find Module …”

    Has noticed an error after executing the command snmpwalk with the indication of MIB instead of OID: ...

  9. ApplicationContext详解以及多个ApplicationContext.xml的相互引用

    如果说BeanFactory是spring的心脏,那么Application就是完整的身躯.ApplicationContext就是由BeanFactory派生出来的. 一.ApplicationCo ...

  10. pygame精灵类实现房子爆炸效果

    # coding=utf8 import random import pygame from pygame.locals import * from cStringIO import StringIO ...